﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Text.RegularExpressions;

namespace ApiDoc
{
    partial class ApiDocumentationManager
    {
        /// <summary>
        /// Returns the FieldDocumentation for <paramref name="field"/>.
        /// </summary>
        /// <remarks>
        /// If the assembly containing <paramref name="field"/> is not already part of the documentation managed by this manager
        /// it will be added with AddAssembly() before generating the documentation for <paramref name="field"/>.
        /// </remarks>
        /// <param name="type"></param>
        /// <returns></returns>
        public FieldDocumentation GetFieldDocumentation(FieldInfo field)
        {
            // Try the cache first.
            string cref = CRef.ReflectionCRefGenerator.NoPrefix.GetCRef(field);

            if (m_fields.ContainsKey(cref)) {
                return m_fields[cref];
            }

            // Add the assembly for the type containing  we don't already have it included.
            if (!m_assemblies.Contains(field.ReflectedType.Assembly)) {
                AddAssembly(field.ReflectedType.Assembly);
            }

            // Cache the result using the type directly.
            var ret = new FieldDocumentation(field, this);
            m_fields.Add(cref, ret);

            return ret;
        }

        /// <summary>
        /// Returns the FieldDocumentation for <paramref name="cref"/>.
        /// </summary>
        /// <param name="cref"></param>
        /// <returns></returns>
        public FieldDocumentation GetFieldDocumentation(string cref)
        {
            // If we have it in the cache then use it.
            if (m_fields.ContainsKey(cref)) {
                return m_fields[cref];
            }

            FieldInfo member = null;
            foreach (var assembly in m_assemblies) {
                member = CRef.ReflectionCRefLookup.GetMemberInfo(assembly, new CRef.CRefIdentifier(cref)) as FieldInfo;
                if (member != null) {
                    break;
                }
            }

            if (member == null) {
                return null; ;
            }

            // Cache the result.
            var ret = new FieldDocumentation(member, this);
            m_fields.Add(cref, ret);

            return ret;
        }

        private Dictionary<string, FieldDocumentation> m_fields = new Dictionary<string, FieldDocumentation>();
    }
}
